//
//  WBNetWorkManager.swift
//  simpleWeibo
//
//  Created by 孙林 on 2018/1/7.
//  Copyright © 2018年 孙林. All rights reserved.
//

import UIKit
import AFNetworking


///swift枚举支持任意基本数据类型
enum WBHTTPMethod {
    case GET
    case POST
}

class WBNetWorkManager: AFHTTPSessionManager {
    ///单例
    static let shared: WBNetWorkManager = {
        //实例化对象
        let instance = WBNetWorkManager()
        //设置响应反序列化支持的数据类型
        instance.responseSerializer.acceptableContentTypes?.insert("text/plain")
        //返回对象
        return instance
    }()
    
    ///用户账号的懒加载属性
    lazy var userAccount = WBUserAccount.init()
    var userLogon: Bool {
        return userAccount.access_token != nil
    }
    
    
    /// 专门负责评价token参数 的网络请求方法
    ///
    /// - Parameters:
    ///   - method: method GET / POST
    ///   - URLString: URLString URLString
    ///   - parameters: parameters 参数字典
    ///   - name: name 接收上传数据的服务器字段(name - 要咨询公司的后台) 例如: 'pic'  默认为 nil 不上传文件
    ///   - data: data 要上传的二进制数据 默认为nil 不上传文件
    ///   - completion: completion 完成回调
    func tokenRequest(method: WBHTTPMethod, URLString: String,parameters: [String: AnyObject]?, name: String? = nil, data: Data? = nil, completion: @escaping (_ json: AnyObject?, _ isSuccess: Bool) -> ()) {
        
        //1先判断token是否有值
        guard userAccount.access_token != nil else {
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: WBUserShouldLoginNotification), object: nil)
            print("token 为空,请先登录")
            
            completion(nil, false)
            return
        }
        
        //2判断参数是否为nil
        var parameters = parameters
        if parameters == nil {
            //实例化parameters
            parameters = [String: AnyObject]()
        }
        parameters!["access_token"] = userAccount.access_token as AnyObject
        
        //3判断 name 和 data
        if let name = name, let data = data {
            //上传文件
            upload(URLString: URLString, parameters: parameters, name: name, data: data, completion: completion)
        } else {
            //调用request 发起真正的网络请求方法
            request(method: method, URLString: URLString, parameters: parameters!, completion: completion)
        }
        
        
    }
    
    
    /// 封装AFN 的上传文件方法
    ///
    /// - Parameters:
    ///   - URLString: URLString URLString
    ///   - parameters: parameters 参数字典
    ///   - name: name 接收上传数据的服务器字段(name - 要咨询公司的后台) 例如: 'pic'
    ///   - data: data 要上传的二进制数据
    ///   - completion: completion 完成回调
    func upload(URLString: String, parameters: [String: AnyObject]?, name: String, data: Data, completion:@escaping (_ json: AnyObject?, _ isSuccess: Bool) -> ()) {
        
        post(URLString, parameters: parameters, constructingBodyWith: { (formData) in
            
            /**
             1 data: 要上传的二进制数据
             2 name: 服务器接收数据的字段名
             3 fileName: 保存在服务器的文件名, 大多数服务器, 现在可以乱写
             4 mimeType: 告诉服务器上传文件的类型, 如果不想告诉, 可以使用 application/octet-stream  image/png image/jpg image/gif
             */
            formData.appendPart(withFileData: data, name: name, fileName: "xxx", mimeType: "application/octet-stream")
            
        }, progress: nil, success: { (task: URLSessionDataTask, json: Any?) in
            
            completion(json as? AnyObject, true)
        }) { (task: URLSessionDataTask?, error: Error) in
            
            //判断token是否过期
            if (task?.response as? HTTPURLResponse)?.statusCode == 403 {
                print("token过期, 请重新登录")
                NotificationCenter.default.post(name: NSNotification.Name(WBUserShouldLoginNotification), object: "bad token")
            }
            print("网络请求错误, \(error)")
            completion(nil, false)
        }
        
    }
    
    /// 使用一个函数封装 AFN的 GET / POST 请求
    ///
    /// - Parameters:
    ///   - method: GET / POST 请求
    ///   - URLString: URL
    ///   - parameters: 请求参数 字典
    ///   - completion: 回调
    func request(method: WBHTTPMethod, URLString: String,parameters: [String: AnyObject], completion: @escaping (_ json: AnyObject?, _ isSuccess: Bool) -> ()) {
        
        let success = { (task: URLSessionDataTask, json: Any?) -> () in
            print("原始网络请求成功 \(String(describing: json))")
            let resultJson = json as? AnyObject
            completion(resultJson, true)
                
            }
        
        let failure = { (task: URLSessionDataTask?, json: Error) -> () in
            print("原始网络请求错误 \(json)")
            //判断token是否过期
            if (task?.response as? HTTPURLResponse)?.statusCode == 403 {
                print("token过期, 请重新登录")
                NotificationCenter.default.post(name: NSNotification.Name(WBUserShouldLoginNotification), object: "bad token")
            }
            completion(nil, false)
            }
        
        if method == .GET {
            get(URLString, parameters: parameters, progress: nil, success: success, failure: failure)
        } else {
            post(URLString, parameters: parameters, progress: nil, success: success, failure: failure)
        }
        
    }

}

